/*
 * Copyright 2009 Eat Local Food, LLC
 * Copyright (c) 2007 osCommerce (this file was written after
 * code review of osCommerce).
 *
 * This file is part of gwtCommerce.
 *
 * gwtCommerce is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * gwtCommerce is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with gwtCommerce.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.elf.gwt.common.client.model;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONValue;

/**
 *  
 */
public class OrderModel extends AbstractModel
{
	protected List<OrderTotalModel> totals;
	protected List<OrderStatusHistoryModel> histories;
	protected List<OrderProductModel> products;
	protected List<OrderPaymentModel> payments;
	protected List<TermsAndConditionsModel> termsAndConditions;
	protected AccountModel accountModel;

	protected int id;
	protected String name;
	protected String company;
	protected String street;
	protected String suburb;
	protected String postcode;
	protected String city;
	protected String state;
	protected String country;
	protected String telephone;
	protected String emailAddress;
	protected String shipToName;
	protected String shipToCompany;
	protected String shipToStreet;
	protected String shipToSuburb;
	protected String shipToPostcode;
	protected String shipToCity;
	protected String shipToState;
	protected String shipToCountry;
	protected String billToName;
	protected String billToCompany;
	protected String billToStreet;
	protected String billToSuburb;
	protected String billToPostcode;
	protected String billToCity;
	protected String billToState;
	protected String billToCountry;
	protected String paymentMethod;
	protected Date lastModified;
	protected Date datePurchased;
	protected int statusId;
	protected String status;
	protected String currencyCode;
	protected double currencyValue;
	protected double total;
	protected String quoteIntroduction;
	protected String quoteEditIntroduction;

	public OrderModel()
	{
		id = 0;
		totals = new ArrayList<OrderTotalModel>();
		histories = new ArrayList<OrderStatusHistoryModel>();
		products = new ArrayList<OrderProductModel>();
		payments = new ArrayList<OrderPaymentModel>();
		termsAndConditions = new ArrayList<TermsAndConditionsModel>();
		accountModel = new AccountModel();
	}

	public void update(JSONObject jsonObject)
	{
		id = 0;
		totals = new ArrayList<OrderTotalModel>();
		histories = new ArrayList<OrderStatusHistoryModel>();
		products = new ArrayList<OrderProductModel>();
		id = convertToInteger(jsonObject,"id");
		name = convertToString(jsonObject,"name");
		company = convertToString(jsonObject,"company");
		street = convertToString(jsonObject,"street_address");
		suburb = convertToString(jsonObject,"suburb");
		postcode = convertToString(jsonObject,"postcode");
		city = convertToString(jsonObject,"city");
		state = convertToString(jsonObject,"state");
		country = convertToString(jsonObject,"country");
		telephone = convertToString(jsonObject,"telephone");
		emailAddress = convertToString(jsonObject,"email_address");

		shipToName = convertToString(jsonObject,"ship_to_name");
		shipToCompany = convertToString(jsonObject,"ship_to_company");
		shipToStreet = convertToString(jsonObject,"ship_to_street_address");
		shipToSuburb = convertToString(jsonObject,"ship_to_suburb");
		shipToPostcode = convertToString(jsonObject,"ship_to_postcode");
		shipToCity = convertToString(jsonObject,"ship_to_city");
		shipToState = convertToString(jsonObject,"ship_to_state");
		shipToCountry = convertToString(jsonObject,"ship_to_country");

		billToName = convertToString(jsonObject,"bill_to_name");
		billToCompany = convertToString(jsonObject,"bill_to_company");
		billToStreet = convertToString(jsonObject,"bill_to_street_address");
		billToSuburb = convertToString(jsonObject,"bill_to_suburb");
		billToPostcode = convertToString(jsonObject,"bill_to_postcode");
		billToCity = convertToString(jsonObject,"bill_to_city");
		billToState = convertToString(jsonObject,"bill_to_state");
		billToCountry = convertToString(jsonObject,"bill_to_country");
		
		paymentMethod = convertToString(jsonObject,"payment_method");
		lastModified = convertToDate(jsonObject,"last_modified");
		datePurchased = convertToDate(jsonObject, "date_purchased");
		statusId = convertToInteger(jsonObject, "status_id");
		status = convertToString(jsonObject, "status");
		currencyCode = convertToString(jsonObject, "currency_code");
		currencyValue = convertToDouble(jsonObject, "currency_value");
		total = convertToDouble(jsonObject, "value");
		quoteIntroduction = convertToString(jsonObject, "quote_introduction");
		quoteEditIntroduction = convertToString(jsonObject, "quote_edit_introduction");

		buildTotals(jsonObject);
		buildHistories(jsonObject);
		buildProducts(jsonObject);
		buildPayments(jsonObject);
		buildTermsAndConditions(jsonObject);

		JSONValue jsonValue = jsonObject.get("account");
		if (jsonValue != null && (jsonObject = jsonValue.isObject()) != null)
		{
			accountModel.update(jsonObject);
		}
		else
		{
			accountModel.update();
		}
	}
	
	protected void buildProducts(JSONObject jsonObject)
	{
		getProducts().clear();
		try {
			JSONValue productValue = jsonObject.get("products");

			if (productValue != null)
			{
				JSONArray jsonArray;
				if ((jsonArray = productValue.isArray()) != null)
				{
					int sz = jsonArray.size();		
					for (int i = 0; i < sz; i++)
					{
						JSONValue jsonValue = jsonArray.get(i);
						JSONObject jsonPObject;
						if ((jsonPObject = jsonValue.isObject()) != null)
						{
							OrderProductModel opModel = new OrderProductModel(jsonPObject);
							addProduct(opModel);
						}
					}
				}
			}
		}
		catch (Exception e) {GWT.log("buildProducts ", e);};
	}
	
	protected void buildTotals(JSONObject jsonObject)
	{
		getTotals().clear();

		try {
			JSONValue totalValue = jsonObject.get("totals");

			if (totalValue != null)
			{
				JSONArray jsonArray;
				if ((jsonArray = totalValue.isArray()) != null)
				{

					int sz = jsonArray.size();		
					for (int i = 0; i < sz; i++)
					{
						JSONValue jsonValue = jsonArray.get(i);
						JSONObject jsonOObject;
						if ((jsonOObject = jsonValue.isObject()) != null)
						{
							OrderTotalModel otModel = new OrderTotalModel(jsonOObject);
							addTotal(otModel);
						}
					}
				}
			}
		}
		catch (Exception e) {GWT.log("buildTotals ", e);}
	}
	
	protected void buildPayments(JSONObject jsonObject)
	{
		getPayments().clear();

		try {
			JSONValue paymentValue = jsonObject.get("payments");

			if (paymentValue != null)
			{
				JSONArray jsonArray;
				if ((jsonArray = paymentValue.isArray()) != null)
				{

					int sz = jsonArray.size();		
					for (int i = 0; i < sz; i++)
					{
						JSONValue jsonValue = jsonArray.get(i);
						JSONObject jsonOObject;
						if ((jsonOObject = jsonValue.isObject()) != null)
						{
							OrderPaymentModel opModel = new OrderPaymentModel(jsonOObject);
							addPayment(opModel);
						}
					}
				}
			}
		}
		catch (Exception e) {GWT.log("buildPayments ", e);}
	}
	
	protected void buildHistories(JSONObject jsonObject)
	{
		getHistories().clear();

		try {
			JSONValue totalValue = jsonObject.get("histories");

			if (totalValue != null)
			{
				JSONArray jsonArray;
				if ((jsonArray = totalValue.isArray()) != null)
				{

					int sz = jsonArray.size();		
					for (int i = 0; i < sz; i++)
					{
						JSONValue jsonValue = jsonArray.get(i);
						JSONObject jsonHObject;
						if ((jsonHObject = jsonValue.isObject()) != null)
						{
							OrderStatusHistoryModel oshModel = new OrderStatusHistoryModel(jsonHObject);
							addHistory(oshModel);
						}
					}
				}
			}
		}
		catch (Exception e) {GWT.log("buildTotals ", e);}
	}
	
	protected void buildTermsAndConditions(JSONObject jsonObject)
	{
		getTermsAndConditions().clear();

		try {
			JSONValue tandcValue = jsonObject.get("tandcs");

			if (tandcValue != null)
			{
				JSONArray jsonArray;
				if ((jsonArray = tandcValue.isArray()) != null)
				{

					int sz = jsonArray.size();		
					for (int i = 0; i < sz; i++)
					{
						JSONValue jsonValue = jsonArray.get(i);
						JSONObject jsonOObject;
						if ((jsonOObject = jsonValue.isObject()) != null)
						{
							TermsAndConditionsModel opModel = new TermsAndConditionsModel(jsonOObject);
							addTermAndCondition(opModel);
						}
					}
				}
			}
		}
		catch (Exception e) {GWT.log("buildTermsAndConditions ", e);}
	}

	public void update(OrderModel model)
	{
		id = model.getId();
		name = model.getName();
		company = model.getCompany();
		street = model.getStreet();
		suburb = model.getSuburb();
		postcode = model.getPostcode();
		city = model.getCity();
		state = model.getState();
		country = model.getCountry();
		telephone = model.getTelephone();
		emailAddress = model.getEmailAddress();
		shipToName = model.getShipToName();
		shipToCompany = model.getShipToCompany();
		shipToStreet = model.getShipToStreet();
		shipToSuburb = model.getShipToSuburb();
		shipToPostcode = model.getShipToPostcode();
		shipToCity = model.getShipToCity();
		shipToState = model.getShipToState();
		shipToCountry = model.getShipToCountry();
		billToName = model.getBillToName();
		billToCompany = model.getBillToCompany();
		billToStreet = model.getBillToStreet();
		billToSuburb = model.getBillToSuburb();
		billToPostcode = model.getBillToPostcode();
		billToCity = model.getBillToCity();
		billToState = model.getBillToState();
		billToCountry = model.getBillToCountry();
		paymentMethod = model.getPaymentMethod();
		lastModified = model.getLastModified();
		datePurchased = model.getDatePurchased();
		statusId = model.getStatusId();
		status = model.getStatus();
		currencyCode = model.getCurrencyCode();
		currencyValue = model.getCurrencyValue();
		totals = model.getTotals();
		histories = model.getHistories();
		products = model.getProducts();
		payments = model.getPayments();
		total = model.getTotal();
		quoteIntroduction = model.getQuoteIntroduction();
	}

	public String getBillToCity() {
		return billToCity;
	}

	public String getBillToCompany() {
		return billToCompany;
	}

	public String getBillToCountry() {
		return billToCountry;
	}

	public String getBillToName() {
		return billToName;
	}

	public String getBillToPostcode() {
		return billToPostcode;
	}

	public String getBillToState() {
		return billToState;
	}

	public String getBillToStreet() {
		return billToStreet;
	}

	public String getBillToSuburb() {
		return billToSuburb;
	}

	public String getCity() {
		return city;
	}

	public String getCompany() {
		return company;
	}

	public String getCountry() {
		return country;
	}

	public String getCurrencyCode() {
		return currencyCode;
	}

	public double getCurrencyValue() {
		return currencyValue;
	}

	public Date getDatePurchased() {
		return datePurchased;
	}

	public String getEmailAddress() {
		return emailAddress;
	}

	public int getId() {
		return id;
	}

	public Date getLastModified() {
		return lastModified;
	}

	public String getName() {
		return name;
	}

	public String getPaymentMethod() {
		return paymentMethod;
	}

	public String getPostcode() {
		return postcode;
	}

	public String getShipToCity() {
		return shipToCity;
	}

	public String getShipToCompany() {
		return shipToCompany;
	}

	public String getShipToCountry() {
		return shipToCountry;
	}

	public String getShipToName() {
		return shipToName;
	}

	public String getShipToPostcode() {
		return shipToPostcode;
	}

	public String getShipToState() {
		return shipToState;
	}

	public String getShipToStreet() {
		return shipToStreet;
	}

	public String getShipToSuburb() {
		return shipToSuburb;
	}

	public String getState() {
		return state;
	}

	public int getStatusId() {
		return statusId;
	}

	public String getStatus() {
		return status;
	}

	public String getStreet() {
		return street;
	}

	public String getSuburb() {
		return suburb;
	}

	public String getTelephone() {
		return telephone;
	}

	public List<OrderTotalModel> getTotals() {
		return totals;
	}

	public void setTotals(List<OrderTotalModel> totals) {
		this.totals = totals;
	}

	public void addTotal(OrderTotalModel total) {
		totals.add(total);
	}

	public List<OrderPaymentModel> getPayments() {
		return payments;
	}

	public void setPayments(List<OrderPaymentModel> payments) {
		this.payments = payments;
	}

	public void addPayment(OrderPaymentModel payment) {
		payments.add(payment);
	}

	public List<OrderStatusHistoryModel> getHistories() {
		return histories;
	}

	public void setHistories(List<OrderStatusHistoryModel> histories) {
		this.histories = histories;
	}

	public void addHistory(OrderStatusHistoryModel history) {
		histories.add(history);
	}

	public List<OrderProductModel> getProducts() {
		return products;
	}

	public void setProducts(List<OrderProductModel> products) {
		this.products = products;
	}

	public void addProduct(OrderProductModel product) {
		products.add(product);
	}

	public List<TermsAndConditionsModel> getTermsAndConditions() {
		return termsAndConditions;
	}

	public void setTermsAndConditions(List<TermsAndConditionsModel> termsAndConditions) {
		this.termsAndConditions = termsAndConditions;
	}

	public void addTermAndCondition(TermsAndConditionsModel termAndCondition) {
		termsAndConditions.add(termAndCondition);
	}

	public void setId(int id) {
		this.id = id;
	}

	public double getTotal() {
		return total;
	}
	
	public AccountModel getAccountModel() {
		return accountModel;
}

	public String getQuoteIntroduction() {
		return quoteIntroduction;
	}

	public String getQuoteEditIntroduction() {
		return quoteEditIntroduction;
	}
}
